﻿#define _CRT_SECURE_NO_WARNINGS 1

#include <iostream>
#include <string>

using namespace std;

//class Person
//{
//public:
//	void Print()
//	{
//		cout << "name:" << _name << endl;
//		cout << "age:" << _age << endl;
//	}
//protected:
//	string _name = "peter"; // 姓名
//	int _age = 18;
//};
//
//// 继承后父类的Person的成员（成员函数+成员变量）都会变成子类的一部分。这里体现出了
////Student和Teacher复用了Person的成员。下面我们使用监视窗口查看Student和Teacher对象，可
////以看到变量的复用。调用Print可以看到成员函数的复用。
//class Student : public Person
//{
//protected:
//	int _stuid; // 学号
//};
//
//class Teacher : public Person
//{
//protected:
//	int _jobid; // 工号
//};
//
//int main()
//{
//	Student s;
//	Teacher t;
//	s.Print();
//	t.Print();
//	t.Print();
//	return 0;
//}


//struct Person
//{
//public:
//// 如果切换为protected: 
//	void Print()
//	{
//		cout << "_age" << endl;
//		cout << "_name" << endl;
//	}
//
//	/*void surface_print()
//	{
//		cout << "Person protected" << endl;
//	}*/
//protected:
//	int _age;
//	string _name;
//};
//
//
//class teacher : public Person
//{
//private:
//	int _work;
//};
//
//class student : public Person
//{
//private:
//	int _student;
//};


//class Person
//{
//protected:
//	string _name; // 姓名
//	string _sex;
//	int _age; // 年龄
//};
//class Student : public Person
//{
//public:
//	int _No; // 学号
//};
//
//void Test()
//{
//	Student sobj;
//	// 1.子类对象可以赋值给父类对象/指针/引用
//	Person pobj = sobj;
//	Person* pp = &sobj;
//	Person& rp = sobj;
//
//	//2.父类对象不能赋值给子类对象
//	// sobj = pobj;
//
//
//	// 3.父类的指针可以通过强制类型转换赋值给子类的指针
//	pp = &sobj;
//	Student * ps1 = (Student*)pp; // 这种情况转换时可以的。
//	ps1->_No = 10;
//
//	// 父类利用指针强转给子类指针
//	pp = &pobj;
//	Student* ps2 = (Student*)pp; // 这种情况转换时虽然可以，但是会存在越界访问的问题
//	ps2->_No = 10;   
//}

//class A
//{
//public:
//	void fun(int i)
//	{
//		cout << "func()" << endl;
//	}
//};
//
//class B : public A
//{
//public:
//	void fun(int i)
//	{
//		A::fun();
//		cout << "func(int i)->" << i << endl;
//	}
//};
//
//void Test()
//{
//	B b;
//	b.fun();
//};
//// 不定向选择：
//// A: 子父func构成重载
//// B: 子父func构成隐藏
//// C: 程序报错
//// D：以上都不对
//
//int main()
//{
//	//teacher a1;
//	//a1.Print();
//	//
//	//student a2;
//	//a2.Print();
//	////a2.surface_print();
//	//a2._age;
//
//	//Person a3; // 子类调用protected
//	//a3.Print(); // public区
//	Test();
//	
//	return 0;
//}


class Person
{
public:
	Person(const char* name = "peter")
		: _name(name)
	{
		cout << "Person()" << endl;
	}

	Person(const Person& p)
		: _name(p._name)
	{
			cout << "Person(const Person& p)" << endl;
	}

	Person& operator=(const Person& p)
	{
		cout << "Person operator=(const Person& p)" << endl;
		if (this != &p)
			_name = p._name;

		return *this;
	}

	~Person()
	{
		cout << "~Person()" << endl;
	}
protected:
	string _name; // 姓名
};

class Student : public Person
{
public:
	// 构造函数
	Student(int num, const char* name = "peter")
		: _num(num)
		,Person(name)  // 通过这种方式对父类进行初始化
	{
		cout << "Student(int,char*)" << endl;
	}

	// 拷贝构造
	Student(const Student& s1)
		:_num(s1._num)
		, Person(s1)    // 通过子类向父类的强转化
	{
		cout << "Student(const Student& )" << endl;
	}

	// 赋值符号重载
	Student& operator=(const Student& s1)
	{
		cout << "operator=" << endl;
		if (this != &s1)
		{
			//Person::operator=(s1);
			_num = s1._num;
			Person(s1);
		}	
		return *this;
	}

	~Student()
	{
		cout << "~Student" << endl;
	}

protected:
	int _num; //学号
};

void Test()
{
	Student a(1);
	Student a2(20);
	a2 = a;
	int x = 10;
}

int main()
{
	Test();
	return 0;
}